package jmine.tec.aom.builder;

import jmine.tec.aom.domain.AbstractPropertyValue;
import jmine.tec.aom.domain.Property;
import jmine.tec.aom.domain.PropertyType;
import jmine.tec.aom.domain.impl.BigDecimalPropertyValue;
import jmine.tec.aom.domain.impl.DoublePropertyValue;
import jmine.tec.aom.domain.impl.IntegerPropertyValue;
import jmine.tec.aom.exception.FillException;
import bancosys.tec.persist.builders.AbstractDBBuilder;

/**
 * @author jrenaut
 */
public class PropertyValueBuilder extends AbstractDBBuilder<AbstractPropertyValue> {

    private Property property = null;

    private boolean locked = false;

    private String value = "some value";

    public static PropertyValueBuilder aPropertyValue() {
        return new PropertyValueBuilder();
    }

    public static PropertyValueBuilder aBigDecimalPropertyValue() {
        PropertyType pt = PropertyTypeBuilder.aPropertyType().withValueClass(BigDecimalPropertyValue.class).build();
        Property p = PropertyBuilder.aProperty().withPropertyType(pt).build();
        return new PropertyValueBuilder().withProperty(p).withValue("1.0");
    }

    public static PropertyValueBuilder aDoublePropertyValue() {
        PropertyType pt = PropertyTypeBuilder.aPropertyType().withValueClass(DoublePropertyValue.class).build();
        Property p = PropertyBuilder.aProperty().withPropertyType(pt).build();
        return new PropertyValueBuilder().withProperty(p).withValue("1.0");
    }

    public static PropertyValueBuilder anIntegerPropertyValue() {
        PropertyType pt = PropertyTypeBuilder.aPropertyType().withValueClass(IntegerPropertyValue.class).build();
        Property p = PropertyBuilder.aProperty().withPropertyType(pt).build();
        return new PropertyValueBuilder().withProperty(p).withValue("1");
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected AbstractPropertyValue doBuild() {
        Property p = this.getProperty();

        AbstractPropertyValue pv = this.createBean(p.getPropertyType().getPropertyValueType());
        pv.setLocked(this.locked);
        pv.setProperty(p);
        try {
            pv.setValueAsString(this.value);
        } catch (FillException e) {
            throw new IllegalStateException("Incorrect string value for property " + p.getMnemonic() + ": " + this.value);
        }
        return pv;
    }

    private Property getProperty() {
        if (this.property == null) {
            this.property = PropertyBuilder.aProperty().save();
        }
        return this.property;
    }

    public PropertyValueBuilder withProperty(Property property) {
        this.property = property;
        return this;
    }

    public PropertyValueBuilder withValue(String value) {
        this.value = value;
        return this;
    }

    public PropertyValueBuilder locked() {
        this.locked = true;
        return this;
    }

}
